/**
 * @file    dr_pc_1363.h
 * @brief   DR协议-1363协议
 * @author  liuwei
 * @version 1.0.1
 * @date    2023-05-30
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-05-08 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "dr_pc_1363.h"
#include "yd1363_app.h"
#include "yd1363_data.h"
#include "cfg_prj.h"
#include "var_mng.h"
#include "param_mng.h"
#include "If_di.h"
#include "parallel.h"
#include "diagnosis.h"
#include "boot_param.h"
/* macro/define --------------------------------------------------------------*/
typedef struct 
{
	uint8_t cmd;
	uint8_t(*p_call_func)(ydt1363_data_type , uint8_t* , uint16_t*);
}yd1363_cmd_type;

#define DR_1363_VERSION              (0x22)
#define DR_CID1_CMD                  (0x4A)
/* local functions -----------------------------------------------------------*/
static uint8_t deal_dr_42h_cmd(ydt1363_data_type recv_data, uint8_t* tx_buf, uint16_t* tx_len);
static uint8_t deal_dr_47h_cmd(ydt1363_data_type recv_data, uint8_t* tx_buf, uint16_t* tx_len);
static uint8_t deal_dr_4Dh_cmd(ydt1363_data_type recv_data, uint8_t* tx_buf, uint16_t* tx_len);
static uint8_t deal_dr_84h_cmd(ydt1363_data_type recv_data, uint8_t* tx_buf, uint16_t* tx_len);
static uint16_t get_volt_state(void);
static uint16_t get_temp_state(void);
static uint16_t get_curr_state(void);
static uint16_t get_alarm_state(void);
static uint16_t get_fet_state(void);
static uint16_t get_di_state(void);

static uint16_t get_salve_volt_state(void);
static uint16_t get_salve_temp_state(void);
static uint16_t get_salve_curr_state(void);
static uint16_t get_salve_alarm_state(void);
static uint16_t get_salve_fet_state(void);
static uint16_t get_salve_di_state(void);

extern master_data_type master_data_reg;
/* static variables ----------------------------------------------------------*/
static ydt1363_data_type recv_data = {0};
static yd1363_cmd_type dr_1363_cmd_func[] = 
{
    {0x42 , deal_dr_42h_cmd },
    {0x47 , deal_dr_47h_cmd },
    {0x4D , deal_dr_4Dh_cmd },
    {0x84 , deal_dr_84h_cmd },
};
#define DR_CMD_NUM         (sizeof(dr_1363_cmd_func)/sizeof(yd1363_cmd_type))
/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
uint8_t dr_pc_1363_analysis(uint8_t *rx_buf , uint16_t rx_len ,uint8_t *tx_buf , uint16_t *tx_len)
{
    uint8_t i = 0;
	if(TRUE == ydt1363_com_analysis(rx_buf , rx_len ,&recv_data))
	{
        if((recv_data.addr == If_di_read_addr()) && (DR_CID1_CMD == recv_data.cid1))
        {
            for( i = 0;i < DR_CMD_NUM; ++ i)
            {
                if(dr_1363_cmd_func[i].cmd == recv_data.cid2)
                {
                    dr_1363_cmd_func[i].p_call_func(recv_data , tx_buf , tx_len);
                    
                    break;
                }
            }
            return TRUE;
        }
        else
        {
            return FALSE;
        }
	}
	else 
		return FALSE;
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
static uint8_t deal_dr_42h_cmd(ydt1363_data_type recv_data, uint8_t* tx_buf, uint16_t* tx_len)
{
    uint16_t tx_idx = 0;
    uint16_t i = 0;
    uint16_t temp_val = 0;
	int16_t stemp = 0;
	uint16_t data_len = 0;

    tx_buf[tx_idx ++ ] = SOI;
    byte_to_ascii(recv_data.ver , &tx_buf[tx_idx]);
    tx_idx += 2;
    byte_to_ascii(recv_data.addr , &tx_buf[tx_idx]);
    tx_idx += 2;
    byte_to_ascii(recv_data.cid1 , &tx_buf[tx_idx]);
    tx_idx += 2;
    byte_to_ascii(0x00 , &tx_buf[tx_idx]);
    tx_idx += 2;
    /* 长度 */
    half_to_ascii(0x00 , &tx_buf[tx_idx]);
    tx_idx += 4;
    byte_to_ascii(0x00 , &tx_buf[tx_idx]);
    tx_idx += 2;
    /* 数据内容 */
    half_to_ascii(var_get_data(VAR_ID_DISP_SOC) , &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(var_get_data(VAR_ID_BATT_VOLT) , &tx_buf[tx_idx]);
    tx_idx += 4;
    byte_to_ascii(CFG_CELL_NUM , &tx_buf[tx_idx]);
    tx_idx += 2;
    for(i = 0;i < CFG_CELL_NUM; ++ i)
    {
        half_to_ascii(var_get_data(VAR_ID_CELL_VOLT01 + i) , &tx_buf[tx_idx]);
        tx_idx += 4;
    }
    stemp = var_get_data(VAR_ID_ENV_TEMP) - 500;
    half_to_ascii(stemp, &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(0, &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = var_get_data(VAR_ID_MOS_TEMP) - 500;
    half_to_ascii(stemp, &tx_buf[tx_idx]);
    tx_idx += 4;
	byte_to_ascii(CFG_TEMP_NUM, &tx_buf[tx_idx]);
    tx_idx += 2;
	for(i = 0;i < CFG_TEMP_NUM; ++ i)
    {
        stemp = var_get_data(VAR_ID_CELL_TEMP01 + i) - 500;
        half_to_ascii(stemp , &tx_buf[tx_idx]);
        tx_idx += 4;
    }
	stemp = var_get_data(VAR_ID_BUS_CURR) - 30000;
	half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(param_get_data(PAR_ID_SOH) , &tx_buf[tx_idx]);
    tx_idx += 4;
	byte_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 2;
	half_to_ascii(param_get_data(PAR_ID_FULL_CAP) , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(var_get_data(VAR_ID_DISP_RCAP) , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(param_get_data(PAR_ID_CYCLE) , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(get_volt_state() , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(get_curr_state() , &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(get_temp_state() , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(get_alarm_state() , &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(get_fet_state() , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(var_get_data(VAR_ID_BLC_NOW_IDX) , &tx_buf[tx_idx]);//junheng
    tx_idx += 4;
    half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
    half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 4;
	half_to_ascii(0 , &tx_buf[tx_idx]);
    tx_idx += 2;
    half_to_ascii(get_di_state() , &tx_buf[tx_idx]);
    tx_idx += 4;

    data_len = yd1363_calc_len(tx_idx - 13);
	half_to_ascii(data_len , &tx_buf[9]);
	temp_val = yd1636_calc_crc(&tx_buf[1] , tx_idx - 1);
	half_to_ascii(temp_val , &tx_buf[tx_idx]);
    tx_idx += 4;
	tx_buf[tx_idx ++ ] = EOI;
   
    *tx_len = tx_idx;
    return TRUE;
}

static uint8_t deal_dr_47h_cmd(ydt1363_data_type recv_data, uint8_t* tx_buf, uint16_t* tx_len)
{
    return TRUE;
}

static uint8_t deal_dr_4Dh_cmd(ydt1363_data_type recv_data, uint8_t* tx_buf, uint16_t* tx_len)
{
    return TRUE;
}

static uint8_t deal_dr_84h_cmd(ydt1363_data_type recv_data, uint8_t* tx_buf, uint16_t* tx_len)
{
    uint16_t tx_idx = 0;
    uint16_t i = 0;
	int16_t stemp = 0;
    int32_t s32_data = 0;
    uint8_t salve_addr = 0;
    uint16_t data_len = 0;
    uint16_t temp_val = 0;
    
    tx_buf[tx_idx ++ ] = SOI;
    byte_to_ascii(recv_data.ver , &tx_buf[tx_idx]);
    tx_idx += 2;
    byte_to_ascii(recv_data.addr , &tx_buf[tx_idx]);
    tx_idx += 2;
    byte_to_ascii(recv_data.cid1 , &tx_buf[tx_idx]);
    tx_idx += 2;
    byte_to_ascii(0x85 , &tx_buf[tx_idx]);
    tx_idx += 2;
    half_to_ascii(0x00 , &tx_buf[tx_idx]);
    tx_idx += 4;
    byte_to_ascii(recv_data.info , &tx_buf[tx_idx]);
    tx_idx += 2;
    salve_addr = recv_data.info;
    if(salve_addr >= CFG_PARALLEL_NUM)
        salve_addr = 0;
    
    s32_data = (master_data_reg.name.salve_data[salve_addr].curr_h16 << 16) + master_data_reg.name.salve_data[salve_addr].curr_l16;
    stemp = s32_data;
    half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].batt_volt;
    half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].soc;
    half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].soh;
    half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].real_cap;
    half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].full_cap;
    half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = param_get_data(PAR_ID_STD_CAP);
    half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].cycle;
    half_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].cell_num;
    byte_to_ascii(stemp , &tx_buf[tx_idx]);
    tx_idx += 2;
    for( i = 0;(i < 16); ++ i)
    {
        stemp = master_data_reg.name.salve_data[salve_addr].cell_volt_buf[i];
        half_to_ascii(stemp , &tx_buf[tx_idx]);
        tx_idx += 4;
    }
    byte_to_ascii(CFG_TEMP_NUM, &tx_buf[tx_idx]);
    tx_idx += 2;
	for(i = 0;i < CFG_TEMP_NUM; ++ i)
    {
        stemp = var_get_data(VAR_ID_CELL_TEMP01 + i) - 500;
        half_to_ascii(stemp , &tx_buf[tx_idx]);
        tx_idx += 4;
    }
    stemp = var_get_data(VAR_ID_MOS_TEMP) - 500;
    half_to_ascii(stemp, &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = var_get_data(VAR_ID_ENV_TEMP) - 500;
    half_to_ascii(stemp, &tx_buf[tx_idx]);
    tx_idx += 4;
    //stemp = master_data_reg.name.com_err_state;
    stemp = 0;
    half_to_ascii(stemp, &tx_buf[tx_idx]);
    tx_idx += 4;
    stemp = get_salve_volt_state();
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
	stemp = get_salve_curr_state();
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
	stemp = get_salve_temp_state();
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
	stemp = get_salve_fet_state();
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
	stemp = get_salve_di_state();
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    stemp = boot_param_read_par(BP_ID_BOOT_VER);
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].version;
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    stemp = 6;
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].max_cell_volt;
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].min_cell_volt;
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].max_temp;
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    stemp = master_data_reg.name.salve_data[salve_addr].min_temp;
    stemp = param_get_data(PAR_ID_OCC_ALM_VAL);
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;
    stemp = param_get_data(PAR_ID_OCD1_ALM_VAL);
    half_to_ascii(stemp, &tx_buf[tx_idx]); 
    tx_idx += 4;

    data_len = yd1363_calc_len(tx_idx - 13);
	half_to_ascii(data_len , &tx_buf[9]);
	temp_val = yd1636_calc_crc(&tx_buf[1] , tx_idx - 1);
	half_to_ascii(temp_val , &tx_buf[tx_idx]);
    tx_idx += 4;
	tx_buf[tx_idx ++ ] = EOI;
    
    *tx_len = tx_idx;
    return TRUE;
}

static uint16_t get_volt_state(void)
{
    uint16_t state = 0;
    if(diag_get_prp(PRP_ID_COV))
        state |= (1 << 0);
    if(diag_get_prp(PRP_ID_CUV))
        state |= (1 << 1);
    if(diag_get_prp(PRP_ID_BOV))
        state |= (1 << 2);
    if(diag_get_prp(PRP_ID_BUV))
        state |= (1 << 3);
    if(diag_get_alarm(ALM_ID_COV))
        state |= (1 << 4);
    if(diag_get_alarm(ALM_ID_CUV))
        state |= (1 << 5);
    if(diag_get_alarm(ALM_ID_BOV))
        state |= (1 << 6);
    if(diag_get_alarm(ALM_ID_BUV))
        state |= (1 << 7);
    if(diag_get_alarm(ALM_ID_VDIFF))
        state |= (1 << 8);
    if(diag_get_prp(PRP_ID_TOL))
        state |= (1 << 11);
    if(diag_get_prp(PRP_ID_COL))
        state |= (1 << 12);
    if(diag_get_prp(PRP_ID_VDIFF))
        state |= (1 << 14);
    
    return state;
}

static uint16_t get_curr_state(void)
{
    uint16_t state = 0;
    if(var_get_data(VAR_ID_CURR_DR) == CURR_DR_CHG)
        state |= (1 << 0);
    if(var_get_data(VAR_ID_CURR_DR) == CURR_DR_DSG)
        state |= (1 << 1);
    if(diag_get_prp(PRP_ID_OCC)||diag_get_prp(PRP_ID_OCC2))
        state |= (1 << 2);
    if(diag_get_prp(PRP_ID_SC))
        state |= (1 << 3);
    if(diag_get_prp(PRP_ID_OCD))
        state |= (1 << 4);
    if(diag_get_prp(PRP_ID_OCD2))
        state |= (1 << 5);
    if(diag_get_alarm(ALM_ID_OCC))
        state |= (1 << 6);
    if(diag_get_alarm(ALM_ID_OCD))
        state |= (1 << 7);

    return state;
}

static uint16_t get_temp_state(void)
{
    uint16_t state = 0;
    if(diag_get_prp(PRP_ID_OTC))
        state |= (1 << 0);
    if(diag_get_prp(PRP_ID_UTC))
        state |= (1 << 1);
    if(diag_get_prp(PRP_ID_OTD))
        state |= (1 << 2);
    if(diag_get_prp(PRP_ID_UTD))
        state |= (1 << 3);
    if(diag_get_prp(PRP_ID_OTE))
        state |= (1 << 4);
    if(diag_get_prp(PRP_ID_UTE))
        state |= (1 << 5);
    if(diag_get_prp(PRP_ID_OTM))
        state |= (1 << 6);
    
    if(diag_get_alarm(ALM_ID_OTC))
        state |= (1 << 8);
    if(diag_get_alarm(ALM_ID_UTC))
        state |= (1 << 9);
    if(diag_get_alarm(ALM_ID_OTD))
        state |= (1 << 10);
    if(diag_get_alarm(ALM_ID_UTD))
        state |= (1 << 11);
    if(diag_get_alarm(ALM_ID_OTE))
        state |= (1 << 12);
    if(diag_get_alarm(ALM_ID_UTE))
        state |= (1 << 13);
    if(diag_get_alarm(ALM_ID_OTM))
        state |= (1 << 14);

    return state;
}

static uint16_t get_alarm_state(void)
{
    uint16_t state = 0;
    if(diag_get_prp(PRP_ID_OTE))
        state |= (1 << 8);
    if(diag_get_prp(PRP_ID_COL))
        state |= (1 << 11);
   // if(diag_get_prp(PRP_ID_COL))
    //    state |= (1 << 12);
    if(diag_get_prp(PRP_ID_TOL))
        state |= (1 << 13);
    if(diag_get_prp(PRP_ID_FT_CMOS))
        state |= (1 << 14);
    if(diag_get_prp(PRP_ID_FT_DMOS))
        state |= (1 << 15);

    return state;
}

static uint16_t get_fet_state(void)
{
    uint16_t state = 0;
    if(var_get_data(VAR_ID_MOS_STATE) & (1 << VAR_MOS_ST_CHG))
        state |= (1 << 0);
    if(var_get_data(VAR_ID_MOS_STATE) & (1 << VAR_MOS_ST_DSG))
        state |= (1 << 1);

    return state;
}

static uint16_t get_di_state(void)
{
    return 0;
}

static uint16_t get_salve_volt_state(void)
{
    
    return 0;
}

static uint16_t get_salve_temp_state(void)
{
    return 0;
}

static uint16_t get_salve_curr_state(void)
{
    return 0;
}

static uint16_t get_salve_alarm_state(void)
{
    return 0;
}

static uint16_t get_salve_fet_state(void)
{
    return 0;
}

static uint16_t get_salve_di_state(void)
{
    return 0;
}

/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
